// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

import UserData from "./SodaUserData";
import Key from "./SodaKey";
import {CodeNum} from "./SodaCode";

type wxCall = (options: { name: string, data?: {}, success?: (res: any) => void, fail?: (res: any) => void }) => Promise<any>;
type wxDownloadFile = (options: { fileID: string, success?: (res: any) => void, fail?: (res: any) => void }) => Promise<any>;
type wxInit = (options: { env: string, traceUser: boolean }) => Promise<any>;
export default class SodaCommon {

    private static _userData: UserData = null;

    /**
     * 游戏审核状态 0为审核中，1为审核通过
     * */
    public static gameReviewStatus: number = 0;

    /**
     * 初始化用户信息
     * @param options
     */
    public static initUserData(options: { guan: number, integral: number, passCount: number, bindPhone: number, lastChangeTime: number, lastExchangeTime: number, historyAllIntegral: number, sodaIntegral: number }) {
        this._userData = new UserData(options);
    }

    /**
     * 获取用户信息
     */
    public static get userData(): UserData {
        return this._userData;
    }

    /**
     * 云开发初始化
     * @param options
     * @returns
     */
    public static wxInit: wxInit = (options: { env: string, traceUser: boolean }): Promise<any> => {
        if (!window['wx']) return null;
        return window['wx'].cloud.init(options);
    };

    /**
     * 云开发函数调用
     * @param options
     * @returns
     */
    public static wxCall: wxCall = (options: { name: string, data?: {}, success?: (res: any) => void, fail?: (res: any) => void }): Promise<any> => {
        if (!window['wx']) return null;
        return window['wx'].cloud.callFunction(options);
    };

    /**
     * 云开发下载
     * @param options
     * @returns
     */
    public static wxDownloadFile: wxDownloadFile = (options: { fileID: string, success?: (res: any) => void, fail?: (res: any) => void }): Promise<any> => {
        if (!window['wx']) return null;
        return window['wx'].cloud.downloadFile(options);
    };

    /**
     * 打开微信小游戏，小程序
     * @param options
     */
    public static openMG(options: { appId: string, path?: string, success?: Function, fail?: Function, extraData?: any, envVersion?: "develop" | "trial" | "release" /**develop    开发版,trial 体验版,release 正式版 */ }) {
        if (window['wx'] && window['wx'].navigateToMiniProgram) {
            window['wx'].navigateToMiniProgram(options)
        }
    }

    public static getGameStatus(): Promise<any> {
        return new Promise((resolve, reject) => {
            this.wxCall({
                name: Key.FN_GET_GAME_STATUS,
                success: (res: any) => {
                    resolve(res.result);
                },
                fail: (res: any) => {
                    reject(0);
                }
            })
        });
    }

    /**
     * 秒转换为时分
     * @param seconds
     * @param isShowHZero
     * @returns
     */
    public static formatSeconds(seconds: number, isShowHZero: boolean = false) {
        const hours = Math.floor(seconds / 3600);
        const minutes = Math.floor(seconds / 60) - hours * 60;
        const _seconds = Math.floor(seconds - hours * 3600 - minutes * 60);

        const add0 = (n: number) => n < 10 ? `0${n}` : n;
        let hzeroContent = isShowHZero ? '00:' : '';
        return `${hours ? add0(hours) + ':' : hzeroContent}${add0(minutes)}:${add0(_seconds)}`;
    };

    /**
     * 短震动
     * @param options
     */
    public static vibrateShort(options: { type: 'heavy' | 'medium' | 'light', success?: Function, fail?: Function, complete?: Function }) {
        if (window['wx'] && window['wx'].vibrateShort) {
            window['wx'].vibrateShort(options);
        }
    }

    /**
     * 长震动
     * @param options
     */
    public static vibrateLong(options?: { success?: Function, fail?: Function, complete?: Function }) {
        if (window['wx'] && window['wx'].vibrateShort) {
            window['wx'].vibrateLong(options);
        }
    }

    /**
     * 检查是否可以增加游戏内积分
     * @returns
     */
    private static checkIsCanAdd(): Boolean {
        // let nt = Date.parse(new Date().toString()) / 1000
        // let lt = this._userData.lastChangeTime;
        // let ltk = this._userData.lastChangeTime + Key.NEED_WAIT_ADD_INTEGRAL_TIME;
        // console.log(nt, lt, ltk, nt <= ltk);
        return (Date.parse(new Date().toString()) / 1000) <= (this._userData.lastChangeTime + Key.NEED_WAIT_ADD_INTEGRAL_TIME);
    }

    /**
     * 检查是否可以兑换汽水积分
     */
    private static checkIsCanExchange(): Boolean {
        if (!this._userData) return true;
        return (Date.parse(new Date().toString()) / 1000) <= (this._userData.lastExchangeTime + Key.NEED_WAIT_EXCHANGE_TIME);
    }

    /**
     * 获取手机号码
     * @returns
     */
    public static getUserPhoneNum() {
        return this._userData ? `${this._userData.bindPhone === -1 ? "" : this._userData.bindPhone}` : "";
    }

    private static _isExchanging: Boolean = false;

    /**
     * 添加用户积分到soda
     * @param phoneNum
     * @returns
     */
    public static userExchange(phoneNum: string): Promise<any> {
        let reg = /^1\d{10}$/;
        if (!reg.test(phoneNum.trim())) {
            return Promise.resolve({
                code: CodeNum.CD_NEG_20002
            });
        }

        if (this.checkIsCanExchange()) {
            return Promise.resolve({
                code: CodeNum.CD_NEG_20001
            });
        }

        if (this._isExchanging) {
            return Promise.resolve({
                code: CodeNum.CD_NEG_20003
            });
        }
        this._isExchanging = true;

        return new Promise((resolve, reject) => {
            this.wxCall({
                name: Key.FN_USER_EXCHANGE,
                data: {
                    phoneNum: phoneNum
                },
                success: (res: any) => {
                    this._isExchanging = false;
                    if (null === res || undefined === res) {
                        resolve({
                            code: CodeNum.CD_NEG_1
                        });
                    }
                    let data = res.result;
                    if (data.msg === CodeNum.CD_NEG_10000) {
                        resolve({
                            code: CodeNum.CD_NEG_10000
                        });
                    } else if (data.code === parseInt(CodeNum.CD_NEG_20001)) {
                        resolve({
                            code: CodeNum.CD_NEG_20001
                        });
                    }
                    this._userData.updateData(data);
                    resolve({
                        code: CodeNum.CD_OK,
                        data: data.exIntegral
                    });
                },
                fail: (res: any) => {
                    this._isExchanging = false;
                    reject();
                }
            })
        });
    }

    private static _isAddIntegral: Boolean = false;

    /**
     * 用户添加游戏内积分
     * @returns
     */
    public static userAddIntegral(): Promise<any> {
        if (this.checkIsCanAdd()) {
            return Promise.resolve({
                code: CodeNum.CD_NEG_20004
            });
        }

        if (this._isAddIntegral) {
            return Promise.resolve({
                code: CodeNum.CD_NEG_20003
            });
        }

        this._isAddIntegral = true;
        return new Promise((resolve, reject) => {
            this.wxCall({
                name: Key.FN_USER_DATA,
                success: (res: any) => {
                    this._isAddIntegral = false;
                    // console.error(res);
                    if (!res.code) {
                        let data = res.result;
                        if (data.code === parseInt(CodeNum.CD_NEG_20000)) {
                            resolve({
                                code: CodeNum.CD_NEG_20000
                            });
                        }
                        this._userData.updateData(data);
                        resolve({
                            code: CodeNum.CD_OK,
                            data: data.rewardIntegral
                        });
                    }
                    resolve({code: CodeNum.CD_NEG_1});
                },

                fail: (res: any) => {
                    this._isAddIntegral = false;
                    reject();
                }
            });
        });
    }

    /**
     * 游戏初始化
     * @param successCallBack
     * @param failCallBack
     */
    public static async gameInit(): Promise<any> {
        await this.wxInit({env: Key.ENV_ID, traceUser: true});

        return new Promise((reslove, reject) => {
            this.wxCall({
                name: Key.FN_GET_USER,
                success: (res: any) => {
                    let data = res.result;
                    this.initUserData(data);
                    reslove(data);
                },
                fail: (res: any) => {
                    reject();
                }
            });
        });

    }

}
